	// STRING

		template<typename T>
		inline red::String::String(const T &ppValue){
			mString << ppValue;
		}

		template<typename T>
		inline String& red::String::operator +(const T &pValue){
			mString << pValue;

			return *this;
		}

		template<typename T>
		inline String& red::String::operator+=(const T &pValue){
			return (*this + pValue);
		}

		inline std::ostream& operator<<(std::ostream& oss, const String &pStr){
			return oss << pStr.str();
		}
	
		inline void red::String::operator=(const std::string &pStr){
			mString.str(pStr);
		}
	
		inline void red::String::operator=(const String &pStr){
			mString.str(pStr);
		}

		inline red::String::operator std::string() const{
			return mString.str();
		}

		inline bool red::String::operator ==(const std::string &pStr) const{
			return this->str() == pStr;
		}

		inline bool red::String::operator !=(const std::string &pStr) const{
			return !(*this == pStr);
		}

		inline std::string red::String::str() const{
			return mString.str();
		}

		inline std::ostringstream& red::String::ostr(){
			return mString;
		}

		inline size_t red::String::size() const{
			return mString.str().size();
		}

		inline bool red::String::Empty() const{
			return str().empty();
		}

		inline bool red::String::IsCommentary() const{
			return str().substr(0,2) == "//";
		}

	// STRING UTILS

		inline StringVector red::StringUtils::SplitString(const std::string &pIn, const std::string &pSep, u32 pMaxSplit){
			StringVector v;
			// pre allocation pour performance
			v.reserve(pMaxSplit ? pMaxSplit + 1 : 5); // 5 nbr max de mot le plus souvent
			u32 splitNbr = 0;
			
			// Parcourt de la chaine 
			size_t p1 = 0, p2;
			do{
				p2 = pIn.find_first_of(pSep, p1);
				if(p2 == p1)
					p1 = p2 + 1;
				else if( p2 == std::string::npos || (pMaxSplit && splitNbr == pMaxSplit)){
					v.push_back(pIn.substr(p1));
					break;
				}else{
					v.push_back(pIn.substr(p1, p2 - p1));
					p1 = p2 + 1;
				}

				p1 = pIn.find_first_not_of(pSep, p1);
				++splitNbr;
			} while(p2 != std::string::npos);
		
			return v;
		}

		inline std::string red::StringUtils::ToLower(const std::string &pStr){
			std::string retStr(pStr.size(), ' ');
			s32 (*pf)(s32) = std::tolower;
			std::transform(pStr.begin(), pStr.end(), retStr.begin(), pf);
			return retStr;
		}

		inline std::string red::StringUtils::ToUpper(const std::string &pStr){
			std::string retStr(pStr.size(), ' ');
			s32 (*pf)(s32) = std::toupper;
			std::transform(pStr.begin(), pStr.end(), retStr.begin(), pf);
			return retStr;
		}

		inline std::string red::StringUtils::GetExtension(const std::string &pFileName){
			std::string::size_type Pos = pFileName.find_first_of(".");
			if( Pos != std::string::npos)
				return pFileName.substr( Pos+1, std::string::npos);
			return "";
		}

		inline std::string red::StringUtils::GetFileName(const std::string &pFileName){
			std::string::size_type pos = pFileName.find_first_of(".");
			if(pos != std::string::npos)
				return pFileName.substr(0, pos);
			return "";
		}

	// STRING CONVERTER

		// STRING TO FLOAT
		inline f32 red::StringConverter::ToFloat(const std::string &pVal){
			std::istringstream str(pVal);
			f32 ret = 0;
			str >> ret;
			return ret;
		}

		// STRING TO INT
		inline s32 red::StringConverter::ToInt(const std::string &pVal){
			std::istringstream str(pVal);
			s32 ret = 0;
			str >> ret;
			return ret;
		}

		// STRING TO UNSIGNED
		inline u32 red::StringConverter::ToUnsigned(const std::string &pVal){
			std::istringstream str(pVal);
			u32 ret = 0;
			str >> ret;
			return ret;
		}

		// STRING TO BOOL
		inline bool red::StringConverter::ToBool(const std::string &pVal){
			return StringUtils::StartsWith(pVal, "true") || StringUtils::StartsWith(pVal, "1") || StringUtils::StartsWith(pVal, "yes");
		}

		// STRING StringConverter::to VECTOR2
		inline Vector2F red::StringConverter::ToVector2(const std::string &pVal){
			Vector2F ret;
			StringVector vec = StringUtils::SplitString(pVal);
			if(vec.size() != 2)
				ret = Vector2F::ZERO;
			else
				ret = Vector2F(ToFloat(vec[0]), ToFloat(vec[1]));
			return ret;
		}

		// STRING StringConverter::to VECTOR3
		inline Vector3F red::StringConverter::ToVector3(const std::string &pVal){
			Vector3F ret;
			StringVector vec = StringUtils::SplitString(pVal);
			if(vec.size() != 3)
				ret = Vector3F::ZERO;
			else
				ret = Vector3F(ToFloat(vec[0]), ToFloat(vec[1]), ToFloat(vec[2]));
			return ret;
		}

		// FLOAT StringConverter::to STRING
		inline String red::StringConverter::ToString(f32 pVal, u16 pPrecision){
			std::ostringstream oss;
			oss.precision(pPrecision);
			oss << pVal;
			return oss.str();
		}

		// DOUBLE StringConverter::to STRING
		inline String red::StringConverter::ToString(f64 pVal, u16 pPrecision){
			std::ostringstream oss;
			oss.precision(pPrecision);
			oss << pVal;
			return oss.str();
		}

		// LINT StringConverter::to STRING
		inline String red::StringConverter::ToString(s32 pVal){
			std::ostringstream oss;
			oss << pVal;
			return oss.str();
		}

		// LUNSIGNED StringConverter::to STRING
		inline String red::StringConverter::ToString(u32 pVal){
			std::ostringstream oss;
			oss << pVal;
			return oss.str();
		}

		// SHORT StringConverter::to STRING
		inline String red::StringConverter::ToString(s16 pVal){
			std::ostringstream oss;
			oss << pVal;
			return oss.str();
		}

		// UNSIGNED StringConverter::to STRING
		inline String red::StringConverter::ToString(u16 pVal){
			std::ostringstream oss;
			oss << pVal;
			return oss.str();
		}
